<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Shaders with jQuery</title>
<script src="../libs/jquery.min.js"></script>
<script src="../libs/gl-matrix-min.js"></script>
<script src="../libs/raf_polyfill.js"></script>
<script id='shader-vs' type="x-shader/x-vertex">
	attribute vec3 aVertexPosition;
	attribute vec3 aVertexColor;
	
	uniform mat4 uMVMatrix;
	uniform mat4 uPMatrix;
	
	varying highp vec4 vColor;
	void main(void){
		gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
		vColor = vec4(aVertexColor, 1.0);
	}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
	varying highp vec4 vColor;
	void main(void){
		gl_FragColor = vColor;
	}
</script>
<script>
	var gl = null,
		canvas = null,
		glProgram = null,
		fragmentShader = null,
		vertexShader = null;
	
	var vPositionAttribute = null,
		verticeBuffer = null,
		vColorAttribute = null,
		colorBuffer = null,
		indexBuffer = null;
	
	var mvMatrix = mat4.create(),
		pMatrix = mat4.create();
	
	var angle = 0.01;
	
	function initWebGL(){
		canvas = document.getElementById("my-canvas");
		try
		{
			gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
		}
		catch (e){}
		
		if (gl){
			initShaders();
			setupBuffers();
			getMatrixUniforms();
			(function animLoop(){
				setupWebGL();
				setMatrixUniforms();
				drawScene();
				requestAnimationFrame(animLoop, canvas);
			})();
		}
		else{
			alert("Error: Your browser does not support WebGL");
		}
	}
	
	function setupWebGL(){
		gl.clearColor(0.1, 0.5, 0.1, 1.0);
		gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
		gl.enable(gl.DEPTH_TEST);
		
		gl.viewport(0,0, canvas.width, canvas.height);
		mat4.perspective(45, canvas.width / canvas.height, 0.1, 100.0, pMatrix);
		mat4.identity(mvMatrix);
		mat4.translate(mvMatrix, [-1.0,-1.0,-7.0]);
		mat4.rotate(mvMatrix, angle, [0.0,11.0,0.0]);
		angle += 0.01;
	}
	
	function initShaders(){
		/*
		$.ajax({
			async: false,
			url: './shader.vs',
			success: function(data){
				vs_source = data.firstChild.textContent;
			},
			datatype: 'xml'
		});
		$.ajax({
			async: false,
			url: './shader.fs',
			success: function(data){
				fs_source = data.firstChild.textContent;
			},
			dataType: 'xml'
		});
		*/
		vs_source = $('#shader-vs').html();
		fs_source = $('#shader-fs').html();
		vertexShader = makeShader(vs_source, gl.VERTEX_SHADER);
		fragmentShader = makeShader(fs_source, gl.FRAGMENT_SHADER);
		
		glProgram = gl.createProgram();
		gl.attachShader(glProgram, vertexShader);
		gl.attachShader(glProgram, fragmentShader);
		gl.linkProgram(glProgram);
		if (!gl.getProgramParameter(glProgram, gl.LINK_STATUS)){
			alert('init shader program');
		}
		gl.useProgram(glProgram);
	}
	
	function makeShader(src, type){
		var shader = gl.createShader(type);
		gl.shaderSource(shader, src);
		gl.compileShader(shader);
		
		if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)){
			alert('compiling shader');
		}
		return shader;
	}
	
	function setupBuffers(){
		var triangleVerticeColors = [ 
					//front face	
					 0.0, 0.0, 1.0,
					 1.0, 1.0, 1.0,
					 0.0, 0.0, 1.0,
					 0.0, 0.0, 1.0,
					 0.0, 0.0, 1.0,
					 1.0, 1.0, 1.0,
				
					//rear face
					 0.0, 1.0, 1.0,
					 1.0, 1.0, 1.0,
					 0.0, 1.0, 1.0,
					 0.0, 1.0, 1.0,
					 0.0, 1.0, 1.0,
					 1.0, 1.0, 1.0,
				];
			
			colorBuffer = gl.createBuffer();
			gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
			gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVerticeColors), gl.STATIC_DRAW);
			
			var triangleVertices = [ 
					//front face
					//bottom left to right,  to top
					0.0, 0.0, 0.0,
					1.0, 0.0, 0.0,
					2.0, 0.0, 0.0,
					0.5, 1.0, 0.0,
					1.5, 1.0, 0.0,
					1.0, 2.0, 0.0,
					
					//rear face
					0.0, 0.0, -2.0,
					1.0, 0.0, -2.0,
					2.0, 0.0, -2.0,
					0.5, 1.0, -2.0,
					1.5, 1.0, -2.0,
					1.0, 2.0, -2.0,
				];
				
			verticeBuffer = gl.createBuffer();
			gl.bindBuffer(gl.ARRAY_BUFFER, verticeBuffer);
			gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.STATIC_DRAW);
			
			var triangleVertexIndices = [ 
					//front face
					0,1,3,
					1,3,4,
					1,2,4,
					3,4,5,
					
					//rear face
					6,7,9,
					7,9,10,
					7,8,10,
					9,10,11,
					
					//left side
					0,3,6,
					3,6,9,
					3,5,9,
					5,9,11,
					
					//right side
					2,4,8,
					4,8,10,
					4,5,10,
					5,10,11,
				];
			
			indexBuffer = gl.createBuffer();
			gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
			gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(triangleVertexIndices), gl.STATIC_DRAW);
	}
	
	function drawScene(){
		vPositionAttribute = gl.getAttribLocation(glProgram, "aVertexPosition");
		gl.enableVertexAttribArray(vPositionAttribute);
		gl.bindBuffer(gl.ARRAY_BUFFER, verticeBuffer);
		gl.vertexAttribPointer(vPositionAttribute, 3, gl.FLOAT, false, 0, 0);
		
		vColorAttribute = gl.getAttribLocation(glProgram, "aVertexColor");
		gl.enableVertexAttribArray(vColorAttribute);
		gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
		gl.vertexAttribPointer(vColorAttribute, 3, gl.FLOAT, false, 0, 0);
		
		gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
		gl.drawElements(gl.TRIANGLES, 16*3, gl.UNSIGNED_SHORT, 0);
	}
	
	function getMatrixUniforms(){
		glProgram.pMatrixUniform = gl.getUniformLocation(glProgram, "uPMatrix");
		glProgram.mvMatrixUniform = gl.getUniformLocation(glProgram, "uMVMatrix");
	}
	
	function setMatrixUniforms(){
		gl.uniformMatrix4fv(glProgram.pMatrixUniform, false, pMatrix);
		gl.uniformMatrix4fv(glProgram.mvMatrixUniform, false, mvMatrix);
	}
</script>
</head>

<body onload="initWebGL()">
	<canvas id="my-canvas" width="400" height="300">No support</canvas>
</body>
</html>
